﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DetectiveCluedo
{
    public partial class GameLogForm : Form
    {
        public GameLogForm()
        {
            InitializeComponent();
        }

        private void GameLogForm_Load(object sender, EventArgs e)
        {
            listBoxMovePlayer.DataSource = CluedoGame.Players.Select(p => p.Name).ToArray();
            listBoxSuspect.DataSource = CluedoGame.Cards.Where(c => c.Type == ECardType.Suspect).Select(s => s.Name).ToArray();
            listBoxWeapon.DataSource = CluedoGame.Cards.Where(c => c.Type == ECardType.Weapon).Select(s => s.Name).ToArray();
            listBoxRoom.DataSource = CluedoGame.Cards.Where(c => c.Type == ECardType.Room).Select(s => s.Name).ToArray();
            listBoxConfirmPlayer.DataSource = new string[] { "(Nobody)" }.Union(CluedoGame.Players.Where(pl => pl.Name != listBoxMovePlayer.SelectedItem.ToString()).Select(p => p.Name)).ToArray();

            setShownCardItems();

            fillGameLogGrid();
        }

        private void listBoxSuspectOrWeaponOrRoom_SelectedIndexChanged(object sender, EventArgs e)
        {
            setShownCardItems();
        }

        private void listBoxMovePlayer_SelectedIndexChanged(object sender, EventArgs e)
        {
            listBoxConfirmPlayer.DataSource = new string[] { "(Nobody)" }.Union(CluedoGame.Players.Where(pl => pl.Name != listBoxMovePlayer.SelectedItem.ToString()).Select(p => p.Name)).ToArray();
            setShownCardItems();
        }

        private void buttonAddLog_Click(object sender, EventArgs e)
        {
            Player movePlayer = CluedoGame.GetPlayerByName(listBoxMovePlayer.SelectedItem.ToString());
            Player confirmPlayer = CluedoGame.GetPlayerByName(listBoxConfirmPlayer.SelectedItem.ToString());
            Card suspectCard = CluedoGame.GetCardByNameAndType(listBoxSuspect.SelectedItem.ToString(), ECardType.Suspect);
            Card weaponCard = CluedoGame.GetCardByNameAndType(listBoxWeapon.SelectedItem.ToString(), ECardType.Weapon);
            Card roomCard = CluedoGame.GetCardByNameAndType(listBoxRoom.SelectedItem.ToString(), ECardType.Room);
            Card shownCard = CluedoGame.GetCardByNameAndType(listBoxShownCard.SelectedItem.ToString(), ECardType.Suspect);
            if (shownCard == null)
                shownCard = CluedoGame.GetCardByNameAndType(listBoxShownCard.SelectedItem.ToString(), ECardType.Weapon);
            if (shownCard == null)
                shownCard = CluedoGame.GetCardByNameAndType(listBoxShownCard.SelectedItem.ToString(), ECardType.Room);

            GameLog gl = new GameLog(movePlayer, confirmPlayer, suspectCard, weaponCard, roomCard, shownCard);
            if (gl.IsInitialized)
                CluedoGame.AddGameLog(gl);

            fillGameLogGrid();

        }

        private void buttonUpdateLog_Click(object sender, EventArgs e)
        {
            if (dataGridView1.CurrentRow.Index != -1 && !dataGridView1.CurrentRow.IsNewRow)
            {
                Player movePlayer = CluedoGame.GetPlayerByName(listBoxMovePlayer.SelectedItem.ToString());
                Player confirmPlayer = CluedoGame.GetPlayerByName(listBoxConfirmPlayer.SelectedItem.ToString());
                Card suspectCard = CluedoGame.GetCardByNameAndType(listBoxSuspect.SelectedItem.ToString(), ECardType.Suspect);
                Card weaponCard = CluedoGame.GetCardByNameAndType(listBoxWeapon.SelectedItem.ToString(), ECardType.Weapon);
                Card roomCard = CluedoGame.GetCardByNameAndType(listBoxRoom.SelectedItem.ToString(), ECardType.Room);
                Card shownCard = CluedoGame.GetCardByNameAndType(listBoxShownCard.SelectedItem.ToString(), ECardType.Suspect);
                if (shownCard == null)
                    shownCard = CluedoGame.GetCardByNameAndType(listBoxShownCard.SelectedItem.ToString(), ECardType.Weapon);
                if (shownCard == null)
                    shownCard = CluedoGame.GetCardByNameAndType(listBoxShownCard.SelectedItem.ToString(), ECardType.Room);

                string q = string.Format("Are you sure to replace:{0}{1} -> {2}{0}{3} -> {4}{0}{5} -> {6}{0}{7} -> {8}{0}{9} -> {10}{0}{11} -> {12}", Environment.NewLine
                    , dataGridView1.CurrentRow.Cells[1].Value.ToString(), movePlayer.Name
                    , dataGridView1.CurrentRow.Cells[2].Value.ToString(), roomCard.Name
                    , dataGridView1.CurrentRow.Cells[3].Value.ToString(), suspectCard.Name
                    , dataGridView1.CurrentRow.Cells[4].Value.ToString(), weaponCard.Name
                    , (!string.IsNullOrEmpty(dataGridView1.CurrentRow.Cells[5].Value.ToString()) ? dataGridView1.CurrentRow.Cells[5].Value.ToString() : "(Nobody)"), ((confirmPlayer != null) ? confirmPlayer.Name : "(Nobody)")
                    , (!string.IsNullOrEmpty(dataGridView1.CurrentRow.Cells[6].Value.ToString()) ? dataGridView1.CurrentRow.Cells[6].Value.ToString() : "(Unknown card)"), ((shownCard != null) ? shownCard.Name : "(Unknown card)")
                );

                if (MessageBox.Show(q, "Confirmation", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                {


                    GameLog gl = new GameLog(movePlayer, confirmPlayer, suspectCard, weaponCard, roomCard, shownCard);
                    if (gl.IsInitialized)
                        CluedoGame.UpdateGameLog(gl, dataGridView1.CurrentRow.Index);

                    fillGameLogGrid();
                }
            }
        }

        private void buttonDeleteLog_Click(object sender, EventArgs e)
        {
            if (dataGridView1.CurrentRow.Index != -1)
            {
                CluedoGame.DeleteGameLog(dataGridView1.CurrentRow.Index);
            }
            fillGameLogGrid();
        }

        private void fillGameLogGrid()
        {
            dataGridView1.Rows.Clear();
            int i = 1;

            foreach (GameLog gl in CluedoGame.GetGameLog())
            {
                dataGridView1.Rows.Insert(0, i.ToString(), gl.MovePlayer.Name, gl.RoomCard.Name, gl.SuspectCard.Name, gl.WeaponCard.Name, ((gl.DisapprovePlayer != null) ? gl.DisapprovePlayer.Name : ""), (gl.ShownCard != null) ? gl.ShownCard.Name : "");
                dataGridView1.Rows[0].Cells[1].Style.BackColor = gl.MovePlayer.Color;

                //dataGridView1.Rows[0].Cells[3].Style.BackColor = CluedoGame.GetPlayerColor(gl.SuspectCard.Name);

                if (gl.DisapprovePlayer != null)
                    dataGridView1.Rows[0].Cells[5].Style.BackColor = gl.DisapprovePlayer.Color;
                i++;
            }

            toolStripStatusLabel1.Text = dataGridView1.Rows.Count.ToString();

            listBoxRoom.Refresh();
            listBoxSuspect.Refresh();
            listBoxWeapon.Refresh();
        }

        private void listBoxConfirmPlayer_SelectedIndexChanged(object sender, EventArgs e)
        {
            setShownCardItems();
        }

        private void setShownCardItems()
        {
            List<string> dataSource = new List<string>();

            if (listBoxSuspect.SelectedItem != null && listBoxWeapon.SelectedItem != null && listBoxRoom.SelectedItem != null)
            {
                Player movePlayer = CluedoGame.GetPlayerByName(listBoxMovePlayer.SelectedItem.ToString());
                Player confirmPlayer = CluedoGame.GetPlayerByName(listBoxConfirmPlayer.SelectedItem.ToString());
                Card suspectCard = CluedoGame.GetCardByNameAndType(listBoxSuspect.SelectedItem.ToString(), ECardType.Suspect);
                Card weaponCard = CluedoGame.GetCardByNameAndType(listBoxWeapon.SelectedItem.ToString(), ECardType.Weapon);
                Card roomCard = CluedoGame.GetCardByNameAndType(listBoxRoom.SelectedItem.ToString(), ECardType.Room);


                if (confirmPlayer != null && confirmPlayer.Equals(CluedoGame.GetYourself()))
                {
                    //var pcil = CluedoGame.GetPlayerCardInfoLog();


                    dataSource.AddRange(

                        from pcil in CluedoGame.GetPlayerCardInfoLog()
                        where pcil.Player.Equals(confirmPlayer)
                            && pcil.Reason == EPlayerCardInfoStatusReason.MyCard
                            && (pcil.Card.Equals(suspectCard) || pcil.Card.Equals(weaponCard) || pcil.Card.Equals(roomCard))
                        select pcil.Card.Name
                    );
                    /*
                    foreach (Card card in CluedoGame.Cards)
                    {
                        PlayerCardInfo pki = CluedoGame.GetPlayersCardInfo(confirmPlayer, card);
                        if (pki.Reason == EPlayerCardInfoStatusReason.MyCard
                            && (pki.Card.Name.Equals(suspectCard.Name) || pki.Card.Name.Equals(weaponCard.Name) || pki.Card.Name.Equals(roomCard.Name)))
                            dataSource.Add(pki.Card.Name);
                    }
                     * */
                }

                else if ((movePlayer.Equals(CluedoGame.GetYourself()) && confirmPlayer != null) /*||
                    (confirmPlayer != null && confirmPlayer.Equals(CluedoGame.GetYourself()))*/)
                {
                    dataSource.Add(suspectCard.Name);
                    dataSource.Add(weaponCard.Name);
                    dataSource.Add(roomCard.Name);
                }

                else
                    dataSource.Add("(Unknown)");

                //string[] sh = new string[] { "", listBoxSuspect.SelectedItem.ToString(), listBoxWeapon.SelectedItem.ToString(), listBoxRoom.SelectedItem.ToString() };
                listBoxShownCard.DataSource = dataSource.ToArray();
            }
        }

        private void listBoxRoomOrSuspectOrWeapon_DrawItem(object sender, DrawItemEventArgs e)
        {
            bool isSolution = false;
            bool isTakenCard = false;
            Card card = null;
            ListBox list = (ListBox)sender;

            if (list.Name == "listBoxRoom")
                card = CluedoGame.GetCardByNameAndType(list.Items[e.Index].ToString(), ECardType.Room);
            if (list.Name == "listBoxSuspect")
                card = CluedoGame.GetCardByNameAndType(list.Items[e.Index].ToString(), ECardType.Suspect);
            if (list.Name == "listBoxWeapon")
                card = CluedoGame.GetCardByNameAndType(list.Items[e.Index].ToString(), ECardType.Weapon);

            Color fontColor = e.ForeColor;
            Color backColor = e.BackColor;
            Font font = e.Font;

            if (CluedoGame.DoesSomeoneHasCard(card))
            {
                //fontColor = Color.Red;
                font = new Font(e.Font.Name, e.Font.Size, FontStyle.Strikeout);
                //fontColor = CluedoGame.GetPlayerCardInfoLog().Where(p => p.Card.Equals(card) && p.PlayerHasCard == true).Select(c => c.Player).Single().Color;
                isTakenCard = true;
            }
            if (CluedoGame.RoomCardSolution != null && CluedoGame.RoomCardSolution.Equals(card) && list.Name == "listBoxRoom" ||
                CluedoGame.SuspectCardSolution != null && CluedoGame.SuspectCardSolution.Equals(card) && list.Name == "listBoxSuspect" ||
                CluedoGame.WeaponCardSolution != null && CluedoGame.WeaponCardSolution.Equals(card) && list.Name == "listBoxWeapon")
            {
                //fontColor = Color.Green;
                font = new Font(e.Font.Name, e.Font.Size, FontStyle.Bold | FontStyle.Underline);
                isSolution = true;
            }


            e.DrawBackground();
            Graphics g = e.Graphics;
            

            // draw the background color you want
            // mine is set to olive, change it to whatever you want
            //g.FillRectangle(new SolidBrush(/*e.BackColor*/ backColor), e.Bounds);


            g.DrawString(list.Items[e.Index].ToString(), font, new SolidBrush(fontColor), new PointF(e.Bounds.X + 13, e.Bounds.Y));
            if(isSolution){
                /*
                SolidBrush blueBrush = new SolidBrush(Color.Blue);
                Rectangle rect = new Rectangle(e.Bounds.X + 1, e.Bounds.Y + 1, e.Bounds.X + 9, e.Bounds.Y + 9);
                g.FillRectangle(blueBrush, rect);
                */
            }
            else if (isTakenCard)
            {
                SolidBrush brushOuter = new SolidBrush(Color.Black);
                Rectangle rectOuter = new Rectangle(e.Bounds.X, e.Bounds.Y, 11, 11);
                g.DrawRectangle(new Pen(Color.Black, 1), rectOuter);

                SolidBrush brushInner = new SolidBrush(CluedoGame.GetPlayerCardInfoLog().Where(p => p.Card.Equals(card) && p.PlayerHasCard == true).Select(c => c.Player).Single().Color);
                Rectangle rectInner = new Rectangle(e.Bounds.X + 1, e.Bounds.Y + 1, 10, 10);
                g.FillRectangle(brushInner, rectInner);

                //g.DrawImageUnscaled(Properties.Resources.TakenCard, e.Bounds);
            }

            e.DrawFocusRectangle();
        }
    }
}
